# coding=utf-8

try:
    from tkinter import *
except ImportError:  # Python 2.x
    PythonVersion = 2
    from Tkinter import *
    from tkFont import Font
    from ttk import *
    from tkMessageBox import *
    import tkFileDialog
else:  # Python 3.x
    PythonVersion = 3
    from tkinter.font import Font
    from tkinter.ttk import *
    from tkinter.messagebox import *

import requests
import re
import os
import time


def decodeData(data):
    i = 0
    result = []
    while i < len(data) - 2:
        byte = data[i: i + 2]
        byte2 = data[i + 2: i + 4]
        if byte == '7D' and byte2 == '01':
            result.append('7D')
            i += 4
        elif byte == '7D' and byte2 == '02':
            result.append('7E')
            i += 4
        else:
            result.append(byte)
            i += 2
    return result


def parse_location(data):
    alarm = ''.join(data[0:8])
    state = ''.join(data[8:16])
    gps = ''.join(data[16:56])
    addition = ''.join(data[56:])
    return alarm, state, gps, addition


def parse_bms(data):
    cmdType = ''.join(data[0:2])
    # dataSize = ''.join(data[2:10])
    # cmdSize = ''.join(data[10:14])
    result = ''
    i = 14
    if cmdType == 'D1':
        while i < len(data):
            try:
                c = ''.join(data[i:i + 2 * 2])
                s = ''.join(data[i + 2 * 2:i + 3 * 2])
                d = ''.join(data[i + 3 * 2:i + 3 * 2 + int(s, 16) * 2])
                if c == '000E':
                    temp = int(d, 16);
                    if temp >= 0x8000:
                        temp = -1 * (temp & ~0x8000)
                    result += '电池温度:' + str(temp / 100.0) + ','
                elif c == '000F':
                    temp = int(d, 16);
                    if temp >= 0x8000:
                        temp = -1 * (temp & ~0x8000)
                    result += '主板温度:' + str(temp / 100.0) + ','
                elif c == '00AA':
                    result += '报警信息:' + str(d) + ','
                elif c == '0001':
                    result += '电池串数:' + str(int(d, 16)) + ','
                elif c == '0003':
                    result += '电池电压:' + str(int(d, 16) / 100.0) + ','
                elif c == '0009':
                    result += '充电保护:' + str(d) + ','
                elif c == '000A':
                    result += '放电保护:' + str(d) + ','
                i += 3 * 2 + int(s, 16) * 2
            except Exception as e:
                print(e)
                break
    elif cmdType == 'D2':
        while i < len(data):
            try:
                c = ''.join(data[i:i + 2 * 2])
                s = ''.join(data[i + 2 * 2:i + 3 * 2])
                d = ''.join(data[i + 3 * 2:i + 3 * 2 + int(s, 16) * 2])
                if c == '0011':
                    result += '充电开关:' + str(d) + ','
                elif c == '0012':
                    result += '放电开关:' + str(d) + ','
                i += 3 * 2 + int(s, 16) * 2
            except Exception as e:
                print(e)
                break
    return result


class App:
    def __init__(self, parent):
        self.gpsData = []
        self.writeHeader = False
        self.date = StringVar()
        self.id = StringVar()
        self.file = StringVar()
        self.startTime = StringVar()
        self.endTime = StringVar()

        self.lb_date = Label(parent, text='日期:', width=8)
        self.lb_date.grid(row=1, column=1, sticky=W)
        self.et_date = Entry(parent, textvariable=self.date, width=24)
        self.et_date.grid(row=1, column=2, pady=4)

        self.lb_id = Label(parent, text='设备ID:', width=8)
        self.lb_id.grid(row=2, column=1, sticky=W)
        self.et_id = Entry(parent, textvariable=self.id, width=24)
        self.et_id.grid(row=2, column=2, pady=4)

        self.lb_file = Label(parent, text='从文件:', width=8)
        self.lb_file.grid(row=3, column=1, sticky=W)
        self.et_file = Entry(parent, textvariable=self.file, width=24)
        self.et_file.grid(row=3, column=2, pady=4)

        self.lb_startTime = Label(parent, text='开始时间:', width=8)
        self.lb_startTime.grid(row=3, column=1, sticky=W)
        self.et_startTime = Entry(parent, textvariable=self.startTime, width=24)
        self.et_startTime.grid(row=3, column=2, pady=4)
        self.lb_startTime.grid_forget()
        self.et_startTime.grid_forget()

        self.lb_endTime = Label(parent, text='结束时间:', width=8)
        self.lb_endTime.grid(row=4, column=1, sticky=W)
        self.et_endTime = Entry(parent, textvariable=self.endTime, width=24)
        self.et_endTime.grid(row=4, column=2, pady=4)
        self.lb_endTime.grid_forget()
        self.et_endTime.grid_forget()

        bt_send = Button(parent, text='开始', command=self.start, width=8)
        bt_send.grid(row=5, column=2, sticky=E)

        self.date.set(time.strftime("%Y%m%d", time.localtime()))
        self.id.set('013800000002')
        self.file.set('')
        self.startTime.set(time.strftime("%H:%M:%S", time.localtime()))
        self.endTime.set(time.strftime("%H:%M:%S", time.localtime(time.time() + 3600)))
        pass

    def start(self):
        dateTime = self.date.get()
        devId = self.id.get()
        filePath = dateTime + '_' + devId + '_gpsLog.txt'
        if os.path.exists(filePath):
            os.remove(filePath)
        if len(self.file.get()) > 0:
            self.getGpsDataFromFile();
        else:
            self.getGPSData()
        if len(self.gpsData) > 0:
            # self.getBoardTemp()
            self.parse_data()
            self.gpsData = []
            showinfo('完成', "结果已保存在\n" + filePath + '中')
        else:
            showinfo('完成', "设备:"+devId+"\n   在:"+dateTime + "号\n没有记录!")

    def getGPSData(self):
        baseUrl = 'http://www.18gps.net/LogData.aspx?'
        req = requests.get('{0}time={1}&macid={2}'.format(baseUrl, self.date.get(), self.id.get()), timeout=5)
        # with open('gpsLog.html', 'w') as f:
        #    f.write(req.text)
        lines = req.text.split('<br />')
        patt = re.compile('\[([0-9-: ]+).*\].*(7E.*7E)$')
        for line in lines:
            try:
                data = patt.findall(line)
                if len(data) > 0:
                    self.gpsData.append(data)
                    # print(data)
            except Exception as e:
                print(e)
        print('total :{0}'.format(len(self.gpsData)))

    def getGpsDataFromFile(self):
        with open(self.file.get(), 'r') as f:
            patt = re.compile('\[([0-9-: ]+).*\].*(7E.*7E)$')
            for line in f:
                try:
                    data = patt.findall(line)
                    if len(data) > 0:
                        self.gpsData.append(data)
                        # print(data)
                except Exception as e:
                    print(e)
        print('total :{0}'.format(len(self.gpsData)))

    def parse_data(self):
        with open(self.date.get()+'_'+self.id.get()+'_gpsLog.txt', 'a', encoding='utf8') as f:
            for item in self.gpsData:
                totalSize = ''
                try:
                    t = item[0][0]
                    tmpData = decodeData(item[0][1])
                    i = 1
                    cmd = ''.join(tmpData[i:i+2])
                    totalSize = ''.join(tmpData[i + 2:i+4])
                    #devId = ''.join(tmpData[i+4:i+10])
                    serial = ''.join(tmpData[i+10:i+12])
                    data = ''.join(tmpData[i+12:i+12+int(totalSize, 16)])
                    if cmd == "0200":
                        #data_list = parse_location(data)
                        #f.write(t + ':' + serial + ':' + cmd + ':' + ','.join(data_list) + '\r\n')
                        pass
                    elif cmd == '0900':
                        result = parse_bms(data)
                        f.write(t + ':' + serial + ':' + cmd + ':')
                        f.write(result)
                        f.write('\r\n')
                except Exception as e:
                    print('totalSize:{0}  {1}'.format(totalSize, e))


def main():
    tk = Tk(className="BMS")
    tk.geometry('240x156+400+220')  # 设置窗口大小  并初始化桌面位置
    tk.title('模块数据分析工具')            # 设置标题
    tk.resizable(width=False, height=False)  # 设置宽高不可变  默认True
    #tk.iconbitmap('.\\ParseMde\\icon.ico')          # 设置左上角图标

    App(tk)
    tk.mainloop()


if __name__ == '__main__':
    main()
